// Fill out your copyright notice in the Description page of Project Settings.

#include "PlayerCharacter.h"
#include "WinstonLogger.h"
#include "Components/CapsuleComponent.h"
#include "GameFramework/CharacterMovementComponent.h"
#include "EnhancedInputComponent.h"
#include "EnhancedInputSubsystems.h"
#include "InputAction.h"
#include "InputMappingContext.h"
#include "Kismet/GameplayStatics.h"

// Sets default values
APlayerCharacter::APlayerCharacter()
{
    // 使用Winston日志记录角色初始化
    FWinstonLogger::Get().Info(TEXT("PlayerCharacter"), TEXT("Player character initializing"));
    
    // 设置角色胶囊体
    GetCapsuleComponent()->InitCapsuleSize(42.f, 96.0f);
    
    // 设置角色属性
    bUseControllerRotationPitch = false; // 角色不跟随控制器俯仰旋转
    bUseControllerRotationYaw = false;   // 角色不跟随控制器偏航旋转
    bUseControllerRotationRoll = false;  // 角色不跟随控制器翻滚旋转
    
    // 配置角色移动组件
    GetCharacterMovement()->bOrientRotationToMovement = true; // 角色朝向随移动方向变化
    GetCharacterMovement()->RotationRate = FRotator(0.0f, 540.0f, 0.0f); // 旋转速率
    GetCharacterMovement()->JumpZVelocity = 600.f; // 跳跃初速度
    GetCharacterMovement()->AirControl = 0.2f; // 空中控制能力
    GetCharacterMovement()->MaxWalkSpeed = 600.f; // 最大行走速度
    GetCharacterMovement()->MaxWalkSpeedCrouched = 300.f; // 蹲伏时的最大速度
    
    // 初始化相机管理器和游戏设置管理器
    CameraManager = nullptr;
    GameSettingsManager = nullptr;
    
    // 记录角色初始化完成
    FWinstonLogger::Get().Debug(TEXT("PlayerCharacter"), TEXT("Player character initialized"));
}

// Called when the game starts or when spawned
void APlayerCharacter::BeginPlay()
{
    Super::BeginPlay();
    
    // 使用Winston日志记录角色初始化
    FWinstonLogger::Get().Info(TEXT("PlayerCharacter"), TEXT("BeginPlay - Character initialized"));
    
    // 获取游戏设置管理器
    GameSettingsManager = UGameSettingsManager::Get(this);
    if (GameSettingsManager)
    {
        // 更新角色设置
        UpdateCharacterSettings();
        FWinstonLogger::Get().Debug(TEXT("PlayerCharacter"), TEXT("Game settings manager initialized"));
    }
    else
    {
        FWinstonLogger::Get().Warning(TEXT("PlayerCharacter"), TEXT("Failed to get game settings manager"));
    }
    
    // 从游戏模式获取相机管理器
    AEmptyLandGameMode* GameMode = Cast<AEmptyLandGameMode>(GetWorld()->GetAuthGameMode());
    if (GameMode)
    {
        CameraManager = GameMode->GetCameraManager();
        if (CameraManager)
        {
            FWinstonLogger::Get().Info(TEXT("PlayerCharacter"), TEXT("Got camera manager from game mode"));
            
            // 设置相机的观察目标为当前角色
            CameraManager->SetTarget(this);
        }
        else
        {
            FWinstonLogger::Get().Warning(TEXT("PlayerCharacter"), TEXT("Camera manager not available in game mode"));
            
            // 尝试查找场景中的相机管理器作为后备方案
            TArray<AActor*> CameraManagers;
            UGameplayStatics::GetAllActorsOfClass(GetWorld(), ACameraManager::StaticClass(), CameraManagers);
            
            if (CameraManagers.Num() > 0)
            {
                CameraManager = Cast<ACameraManager>(CameraManagers[0]);
                FWinstonLogger::Get().Info(TEXT("PlayerCharacter"), TEXT("Found existing camera manager in scene"));
                CameraManager->SetTarget(this);
            }
            else
            {
                FWinstonLogger::Get().Error(TEXT("PlayerCharacter"), TEXT("No camera manager found, camera functionality disabled"));
            }
        }
    }
    else
    {
        FWinstonLogger::Get().Warning(TEXT("PlayerCharacter"), TEXT("Could not get game mode"));
    }
    
    // 获取玩家控制器并设置输入映射上下文
    if (APlayerController* PlayerController = Cast<APlayerController>(Controller))
    {
        if (UEnhancedInputLocalPlayerSubsystem* Subsystem = ULocalPlayer::GetSubsystem<UEnhancedInputLocalPlayerSubsystem>(PlayerController->GetLocalPlayer()))
        {
            // 添加默认输入映射上下文
            Subsystem->AddMappingContext(DefaultMappingContext, 0);
            FWinstonLogger::Get().Debug(TEXT("PlayerCharacter"), TEXT("Input mapping context added successfully"));
        }
        else
        {
            FWinstonLogger::Get().Warning(TEXT("PlayerCharacter"), TEXT("Failed to get EnhancedInputLocalPlayerSubsystem"));
        }
    }
    else
    {
        FWinstonLogger::Get().Warning(TEXT("PlayerCharacter"), TEXT("No valid PlayerController found"));
    }
}

// Called every frame
void APlayerCharacter::Tick(float DeltaTime)
{
    Super::Tick(DeltaTime);
    
    // 这里可以添加帧更新逻辑，如角色状态检测等
    
    // 检查冲刺状态变化（可选的调试信息）
    static bool bLastSprintState = false;
    bool bCurrentSprintState = IsSprinting();
    
    if (bCurrentSprintState != bLastSprintState)
    {
        FWinstonLogger::Get().Debug(
            TEXT("PlayerCharacter"), 
            TEXT("Sprint state changed to: %s"), 
            bCurrentSprintState ? TEXT("true") : TEXT("false")
        );
        bLastSprintState = bCurrentSprintState;
    }
}

// Called to bind functionality to input
void APlayerCharacter::SetupPlayerInputComponent(UInputComponent* PlayerInputComponent)
{
    Super::SetupPlayerInputComponent(PlayerInputComponent);
    
    // 检查并设置增强输入组件
    if (UEnhancedInputComponent* EnhancedInputComponent = CastChecked<UEnhancedInputComponent>(PlayerInputComponent))
    {
        // 绑定移动输入
        EnhancedInputComponent->BindAction(MoveAction, ETriggerEvent::Triggered, this, &APlayerCharacter::Move);
        
        // 绑定视角输入
        EnhancedInputComponent->BindAction(LookAction, ETriggerEvent::Triggered, this, &APlayerCharacter::Look);
        
        // 绑定跳跃输入
        EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Triggered, this, &APlayerCharacter::Jump);
        EnhancedInputComponent->BindAction(JumpAction, ETriggerEvent::Completed, this, &APlayerCharacter::StopJumping);
        
        // 绑定冲刺输入
        EnhancedInputComponent->BindAction(SprintAction, ETriggerEvent::Triggered, this, &APlayerCharacter::Sprint);
        EnhancedInputComponent->BindAction(SprintAction, ETriggerEvent::Completed, this, &APlayerCharacter::Sprint);
    }
}

/**
 * 处理角色移动
 * @param Value 输入动作值，包含2D向量表示移动方向
 */
void APlayerCharacter::Move(const FInputActionValue& Value)
{
    // 获取2D移动向量
    FVector2D MovementVector = Value.Get<FVector2D>();

    // 记录移动输入（仅在Debug级别记录详细信息）
    FWinstonLogger::Get().Debug(
        TEXT("PlayerCharacter"), 
        TEXT("Move input received: X=%f, Y=%f"), 
        MovementVector.X, 
        MovementVector.Y
    );

    if (Controller != nullptr)
    {
        // 获取控制器旋转
        const FRotator Rotation = Controller->GetControlRotation();
        const FRotator YawRotation(0, Rotation.Yaw, 0); // 只保留偏航旋转
        
        // 获取前向和右侧向量
        const FVector ForwardDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::X);
        const FVector RightDirection = FRotationMatrix(YawRotation).GetUnitAxis(EAxis::Y);
        
        // 应用移动输入
        AddMovementInput(ForwardDirection, MovementVector.Y);
        AddMovementInput(RightDirection, MovementVector.X);
    }
    else
    {
        FWinstonLogger::Get().Warning(TEXT("PlayerCharacter"), TEXT("Move called but Controller is null"));
    }
}

void APlayerCharacter::Look(const FInputActionValue& Value)
{
    // 获取输入值
    FVector2D LookAxisVector = Value.Get<FVector2D>();
    
    // 处理水平视角输入（yaw） - 旋转角色
    if (APlayerController* PC = Cast<APlayerController>(GetController()))
    {
        // 旋转角色（水平方向）
        float YawInput = LookAxisVector.X;
        AddControllerYawInput(YawInput);
        
        // 处理垂直视角输入（pitch） - 调整相机
        if (CameraManager)
        {
            // 获取游戏设置管理器中的相机灵敏度
            float Sensitivity = 1.0f;
            if (GameSettingsManager)
            {
                Sensitivity = GameSettingsManager->GetCameraSensitivity();
            }
            
            // 获取当前相机旋转
            FRotator CurrentRotation = CameraManager->GetCamera()->GetRelativeRotation();
            
            // 计算新的俯仰角（应用灵敏度，并限制在-85到85度之间，避免过度旋转）
            float PitchAdjustment = -LookAxisVector.Y * Sensitivity;
            float NewPitch = FMath::Clamp(CurrentRotation.Pitch + PitchAdjustment, -85.0f, 85.0f);
            
            // 设置新的相机旋转
            CameraManager->SetCameraRotation(FRotator(NewPitch, 0.0f, 0.0f));
            
            FWinstonLogger::Get().Debug(TEXT("PlayerCharacter"), 
                TEXT("Camera rotated: Pitch=%f, Sensitivity=%f"), 
                NewPitch, Sensitivity);
        }
        else
        {
            FWinstonLogger::Get().Warning(TEXT("PlayerCharacter"), TEXT("Look input received but no camera manager available"));
        }
    }
}

/**
 * 处理跳跃动作
 */
void APlayerCharacter::Jump()
{
    // 记录跳跃事件
    FWinstonLogger::Get().Info(TEXT("PlayerCharacter"), TEXT("Jump action triggered"));
    
    // 检查是否在地面上
    if (GetCharacterMovement()->IsMovingOnGround())
    {
        FWinstonLogger::Get().Debug(TEXT("PlayerCharacter"), TEXT("Jump initiated - on ground"));
    }
    else
    {
        FWinstonLogger::Get().Debug(TEXT("PlayerCharacter"), TEXT("Jump attempted - not on ground"));
    }
    
    // 通过高级移动组件执行跳跃，这样可以利用其自定义跳跃逻辑
    if (UAdvancedCharacterMovementComponent* AdvancedMovement = GetAdvancedMovementComponent())
    {
        // 触发跳跃
        Super::Jump();
        
        // 记录跳跃信息，包括是否在冲刺
        bool bIsSprinting = AdvancedMovement->IsSprinting();
        FWinstonLogger::Get().Info(
            TEXT("PlayerCharacter"), 
            TEXT("Jump action performed, Sprinting=%s"), 
            bIsSprinting ? TEXT("Yes") : TEXT("No")
        );
    }
    else
    {
        // 如果没有高级移动组件，回退到标准跳跃
        Super::Jump();
        FWinstonLogger::Get().Info(TEXT("PlayerCharacter"), TEXT("Jump action performed using default movement"));
    }
}

UAdvancedCharacterMovementComponent* APlayerCharacter::GetAdvancedMovementComponent() const
{
    return Cast<UAdvancedCharacterMovementComponent>(GetCharacterMovement());
}

void APlayerCharacter::Sprint(const FInputActionValue& Value)
{
    // 获取输入值（布尔值）
    bool bSprintRequested = Value.Get<bool>();
    
    // 获取高级移动组件并设置冲刺状态
    if (UAdvancedCharacterMovementComponent* AdvancedMovement = GetAdvancedMovementComponent())
    {
        AdvancedMovement->SetSprinting(bSprintRequested);
        
        // 记录冲刺状态变化
        FWinstonLogger::Get().Debug(
            TEXT("PlayerCharacter"), 
            TEXT("Sprint requested: %s"), 
            bSprintRequested ? TEXT("true") : TEXT("false")
        );
    }
    else
    {
        FWinstonLogger::Get().Warning(TEXT("PlayerCharacter"), TEXT("Advanced movement component not found"));
    }
}

bool APlayerCharacter::IsSprinting() const
{
    if (UAdvancedCharacterMovementComponent* AdvancedMovement = GetAdvancedMovementComponent())
    {
        return AdvancedMovement->IsSprinting();
    }
    return false;
}

float APlayerCharacter::GetSprintEnergyPercentage() const
{
    if (UAdvancedCharacterMovementComponent* AdvancedMovement = GetAdvancedMovementComponent())
    {
        float MaxTime = AdvancedMovement->GetMaxSprintTime();
        float RemainingTime = AdvancedMovement->GetCurrentSprintTimeRemaining();
        
        if (MaxTime > 0.0f)
        {
            return RemainingTime / MaxTime;
        }
    }
    return 0.0f;
}

void APlayerCharacter::SetCameraManager(ACameraManager* NewCameraManager)
{
    CameraManager = NewCameraManager;
    
    // 如果设置了新的相机管理器，将其目标设置为当前角色
    if (CameraManager)
    {
        CameraManager->SetTarget(this);
        FWinstonLogger::Get().Debug(
            TEXT("PlayerCharacter"), 
            TEXT("Camera manager set: %s"), 
            *CameraManager->GetName()
        );
    }
    else
    {
        FWinstonLogger::Get().Warning(TEXT("PlayerCharacter"), TEXT("Camera manager cleared"));
    }
}

ACameraManager* APlayerCharacter::GetCameraManager() const
{
    return CameraManager;
}

void APlayerCharacter::UpdateCharacterSettings()
{
    if (!GameSettingsManager)
    {
        FWinstonLogger::Get().Warning(TEXT("PlayerCharacter"), TEXT("Game settings manager not available"));
        return;
    }
    
    // 获取高级移动组件
    UAdvancedCharacterMovementComponent* AdvancedMovement = GetAdvancedMovementComponent();
    if (!AdvancedMovement)
    {
        FWinstonLogger::Get().Warning(TEXT("PlayerCharacter"), TEXT("Advanced movement component not available"));
        return;
    }
    
    // 应用移动速度设置
    float WalkSpeed = GameSettingsManager->GetWalkSpeed();
    float SprintSpeed = GameSettingsManager->GetSprintSpeed();
    
    // 设置普通行走速度
    GetCharacterMovement()->MaxWalkSpeed = WalkSpeed;
    
    // 设置冲刺速度（通过高级移动组件）
    AdvancedMovement->SetSprintSpeedMultiplier(SprintSpeed / WalkSpeed);
    
    // 记录设置更新
    FWinstonLogger::Get().Debug(
        TEXT("PlayerCharacter"), 
        TEXT("Character settings updated - WalkSpeed: %f, SprintSpeed: %f"), 
        WalkSpeed, SprintSpeed
    );
    
    // 如果相机管理器存在，应用相机设置
    if (CameraManager)
    {
        CameraManager->SetCameraSensitivity(GameSettingsManager->GetCameraSensitivity());
    }
}